package cn.sxt.clinic.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import cn.sxt.clinic.shiro.CustomRealm;
import cn.sxt.clinic.shiro.MyFormAuthenticationFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.authc.LogoutFilter;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Properties;

@Configuration
public class ShiroConfig {

    //配置Shiro方言
    @Bean
    public ShiroDialect shiroDialect(){

        return new ShiroDialect();
    }
    /*配置核心过滤器工厂*/
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        //配置验证失败跳转的页面
        shiroFilterFactoryBean.setLoginUrl("/admin/loginErr");
        //配置验证成功的跳转界面
        shiroFilterFactoryBean.setSuccessUrl("/index");

        //配置放行的匿名过滤器
        HashMap<String, String> filterChainDefinitionMap = new HashMap<>();
        //放行静态资源
        filterChainDefinitionMap.put("/h-ui/**","anon");
        filterChainDefinitionMap.put("/h-ui.admin/**","anon");
        filterChainDefinitionMap.put("/images/**","anon");
        filterChainDefinitionMap.put("/lib/**","anon");
        //放行登录页面
        filterChainDefinitionMap.put("/admin/loginPage","anon");

        //配置退出过滤器
        filterChainDefinitionMap.put("/logout","logout");
        filterChainDefinitionMap.put("/**","authc");

       shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        /*设置核心安全管理器·*/
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager());

        //配置自定义过滤器
        HashMap<String, Filter> filterMap = new HashMap<>();
        filterMap.put("logout",logoutFilter());
        filterMap.put("authc",new MyFormAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        return shiroFilterFactoryBean;
    }

    /*配置核心安全管理器*/
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //配置自定义Realm
        defaultWebSecurityManager.setRealm(customRealm());

        //配置缓存管理器
        defaultWebSecurityManager.setCacheManager(cacheManager());
        //配置记住我管理器
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());


        return defaultWebSecurityManager;
    }

    //配置自定义realm
    @Bean
    public CustomRealm customRealm(){
        CustomRealm customRealm = new CustomRealm();

        //配置凭证匹配器
        customRealm.setCredentialsMatcher(hashedCredentialsMatcher());

        return customRealm;
    }
    //配置凭证匹配器
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //设置加密方式
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
        //设置加密次数
        hashedCredentialsMatcher.setHashIterations(3);
        return hashedCredentialsMatcher;
    }

    //配置自定义的logout过滤器
    public LogoutFilter logoutFilter(){
        LogoutFilter logoutFilter = new LogoutFilter();
        logoutFilter.setRedirectUrl("/admin/loginPage");
        return logoutFilter;
    }
    //配置记住我管理器
    @Bean
    public RememberMeManager rememberMeManager(){
        return new CookieRememberMeManager();
    }
    //配置缓存管理器
    @Bean
    public CacheManager cacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        return ehCacheManager;
    }


    //开启shiro支持注解配置
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {

        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }

    //设置Spring框架支持shiro注解配置
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;

    }

    //创建对springgmvc抛出异常解析器
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
        Properties properties = new Properties();
        properties.put("org.apache.shiro.authz.UnauthorizedException","unauthorized");

        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return  simpleMappingExceptionResolver;
    }
}
